CoCalc Logo Icon
DocsShareSupport News Sign UpSign In
Views: 100
Image: ubuntu2004
Embed | Download | Raw |
Kernel: Python 3 (ipykernel)

MAXIMUM SET SPLITTING / Максимальное расщепление множеств

import random from IPython.core.display import SVG import pyomo.environ as pyo from pysat.solvers import Solver from pysat.formula import CNF import py_svg_combinatorics as psc from ipywidgets import widgets, HBox from collections import Counter from pprint import pprint from random import randint import numpy as np from IPython.display import IFrame import IPython from copy import copy import os from pathlib import Path from collections import defaultdict from itertools import combinations nbname = '' try: nbname = __vsc_ipynb_file__ except: if 'COCALC_JUPYTER_FILENAME' in os.environ: nbname = os.environ['COCALC_JUPYTER_FILENAME'] title_ = Path(nbname).stem.replace('-', '_').title() IFrame(f'https://discopal.ispras.ru/index.php?title=Hardprob/{title_}&useskin=cleanmonobook', width=1280, height=300)
--------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) Cell In[4], line 4 2 from IPython.core.display import SVG 3 import pyomo.environ as pyo ----> 4 from pysat.solvers import Solver 5 from pysat.formula import CNF 6 import py_svg_combinatorics as psc ModuleNotFoundError: No module named 'pysat.solvers'

Постановка задачи

Задача разрешения — для данного семейства «S» подмножеств конечного множества «U» решить, существует ли разбиение «U» на два подмножества элементов U1U_1, U2U_2 элементы, что SS «расщепляется» этим разбиением, т. е. ни один из элементов S не находится целиком в U1U_1 или U2U_2. Эту проблему иногда называют 2-раскрашиваемостью гиперграфа.

Оптимизационная версия этой задачи называется «расщеплением максимального набора» и требует найти разбиение, которое максимизирует количество расщепляемых элементов S.

https://en.wikipedia.org/wiki/Set_splitting_problem

def get_random_subsets(N, sizes): res = [] for size_, repeat_ in sizes: for _ in range(repeat_): # ok = False # while not ok: # set_ = set(f"{i:02}" for i in np.random.choice(np.arange(1, N), size_)) # if len(set_) == size_: # ok = True set_ = set() while len(set_) != size_: set_ = set(f"{i:02}" for i in np.random.choice(np.arange(1, N), size_)) res.append(set_) return res
N = 20 sets = get_random_subsets(N, [(2, 10), (3, 2), (8, 1)]) # [(num_of_elements, num_of_subset)]
svg = psc.subsets2svg(sets) SVG(data=svg) # Генерация происходит сверху вниз, вы можете наглядно проверить, что программа сгенирировала то, что надо

Реализация в Pyomo

def print_solution(m): for v in m.component_data_objects(pyo.Var): if v.value and v.value > 0: print(str(v), v.value)
def get_model(sets): sets_ = sets if isinstance(sets_, dict): sets_ = [val for _, val in sets_.items()] model = pyo.ConcreteModel() model.S = [set(str(item) for item in sublist) for sublist in sets_] # список подмножеств model.m = len(model.S) # длина подмножества по вертикали model.I = range(model.m) model.U = sorted(set([str(item) for sublist in sets_ for item in sublist])) # universe множество всех элементов (отсортированных) model.n = len(model.U) # длина подмножества по горизонтали model.J = range(model.n) # как мы делаем разрез по элементам model.x = pyo.Var(model.J, domain=pyo.Binary) # пересекает ли подмножество этот разрез model.y = pyo.Var(model.I, domain=pyo.Binary) model.количество_разрезанных_подмножеств = pyo.Objective(expr = sum( model.y[i] for i in model.I), sense=pyo.maximize) # Для корректного разреза мы должны как выбирать, так и не выбирать элемент: # Выбираем элемент @model.Constraint(model.I) def надо_что_то_выбрать_в_множестве_чтобы_считать_его_разрезанным(m, i): return sum(m.x[j] for j in m.J if m.U[j] in m.S[i]) >= m.y[i] # Не выбираем элемент @model.Constraint(model.I) def надо_что_то_выбрать_в_множестве_чтобы_считать_его_разрезанным2(m, i): return len(m.S[i]) - sum(m.x[j] for j in m.J if m.U[j] in m.S[i]) >= m.y[i] return model m = get_model(sets) m.U, m.S
(['01', '02', '03', '04', '05', '09', '10', '12', '13', '14', '15', '17', '18', '19'], [{'03', '13'}, {'09', '18'}, {'12', '19'}, {'13', '14'}, {'10', '13'}, {'02', '17'}, {'09', '18'}, {'05', '17'}, {'01', '15'}, {'04', '10'}, {'05', '12', '19'}, {'04', '09', '18'}, {'02', '03', '04', '05', '12', '14', '18', '19'}])
ilp_solver = pyo.SolverFactory('cbc') ilp_solver.solve(m).write() print_solution(m)
# ========================================================== # = Solver Results = # ========================================================== # ---------------------------------------------------------- # Problem Information # ---------------------------------------------------------- Problem: - Name: unknown Lower bound: 13.0 Upper bound: 13.0 Number of objectives: 1 Number of constraints: 26 Number of variables: 27 Number of binary variables: 27 Number of integer variables: 27 Number of nonzeros: 13 Sense: maximize # ---------------------------------------------------------- # Solver Information # ---------------------------------------------------------- Solver: - Status: ok User time: -1.0 System time: 0.01 Wallclock time: 0.01 Termination condition: optimal Termination message: Model was solved to optimality (subject to tolerances), and an optimal solution is available. Statistics: Branch and bound: Number of bounded subproblems: 0 Number of created subproblems: 0 Black box: Number of iterations: 0 Error rc: 0 Time: 0.09720849990844727 # ---------------------------------------------------------- # Solution Information # ---------------------------------------------------------- Solution: - number of solutions: 0 number of solutions displayed: 0 x[3] 1.0 x[8] 1.0 x[10] 1.0 x[11] 1.0 x[12] 1.0 x[13] 1.0 y[0] 1.0 y[1] 1.0 y[2] 1.0 y[3] 1.0 y[4] 1.0 y[5] 1.0 y[6] 1.0 y[7] 1.0 y[8] 1.0 y[9] 1.0 y[10] 1.0 y[11] 1.0 y[12] 1.0
selected_items = [m.U[j] for j in m.J if m.x[j].value > 0] selected_items
['04', '13', '15', '17', '18', '19']
selected_sets = [i for i in m.I if m.y[i].value > 0] selected_sets
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
SVG(psc.subsets2svg(sets, selected=selected_sets, selected_items=selected_items))
Image in a Jupyter notebook
sets
[{'03', '13'}, {'09', '18'}, {'12', '19'}, {'13', '14'}, {'10', '13'}, {'02', '17'}, {'09', '18'}, {'05', '17'}, {'01', '15'}, {'04', '10'}, {'05', '12', '19'}, {'04', '09', '18'}, {'02', '03', '04', '05', '12', '14', '18', '19'}]

| image.png | image.png | image.png |

cnf3 = CNF(from_clauses=psc.rand3cnf(2, 6)) cnf3.clauses
[[-2, -1, -4], [4, -3, -2]]
from pysat.solvers import Solver solver = Solver(bootstrap_with=cnf3) res = solver.solve() res
True
print(solver.get_model())
[-1, -2, -3, -4]
print(list(solver.enum_models()))
[[-1, -2, -3, -4], [-1, -2, 3, -4], [-1, -2, 3, 4], [1, -2, 3, 4], [1, -2, -3, 4], [-1, -2, -3, 4], [1, -2, -3, -4], [1, -2, 3, -4], [1, 2, -3, -4], [-1, 2, -3, -4], [-1, 2, -3, 4], [-1, 2, 3, 4]]
def lit2str(lit, i=None): ''' литерал в элемент-строку ''' xn = abs(lit) mod = '' if i is not None: mod = f'^{{{i}}}' res = f'x{mod}_{{{xn}}}' if lit < 0: res = f'\overline{{{res}}}' # res = f'¬{{{res}}}' return res
# def clause2tex(clause): # ''' # скобка в латех-строку # ''' # res = '∧'.join([lit2str(l) for l in clause]) # return res 0
0
def cnf32setsplitting(cnf): ''' Будем считать, что на входе 3SAT формула. Можно улучшить и т.п. ''' n = cnf.nv m = len(cnf.clauses) sets = {} # для всех переменных добавляем пары литералов # разрезать это множество — выбрать значение. for j in range(1, n+1): sets[f'x_{{{j}}}'] = [lit2str(j), lit2str(-j)] for i in range(m): clause = cnf.clauses[i] # Для скобок делает «отрезание от нуля» — специального символа «О» clause_set = ['O'] for lit in clause: sets[f'C_{{{i}}}({lit2str(lit)})'] = [lit2str(lit, i), lit2str(-lit)] clause_set.append(lit2str(lit, i)) sets[f'C_{{{i}}}'] = clause_set return sets
cnf3 = CNF(from_clauses=psc.rand3cnf(1, 10)) cnf3.clauses
[[3, -2, 1]]
sets = cnf32setsplitting(cnf3) pprint(sets)
{'C_{0}': ['O', 'x^{0}_{3}', '\\overline{x^{0}_{2}}', 'x^{0}_{1}'], 'C_{0}(\\overline{x_{2}})': ['\\overline{x^{0}_{2}}', 'x_{2}'], 'C_{0}(x_{1})': ['x^{0}_{1}', '\\overline{x_{1}}'], 'C_{0}(x_{3})': ['x^{0}_{3}', '\\overline{x_{3}}'], 'x_{1}': ['x_{1}', '\\overline{x_{1}}'], 'x_{2}': ['x_{2}', '\\overline{x_{2}}'], 'x_{3}': ['x_{3}', '\\overline{x_{3}}']}
SVG(psc.subsets2svg(sets))
Image in a Jupyter notebook
m = get_model(sets) m.U, m.S
(['O', '\\overline{x^{0}_{2}}', '\\overline{x_{1}}', '\\overline{x_{2}}', '\\overline{x_{3}}', 'x^{0}_{1}', 'x^{0}_{3}', 'x_{1}', 'x_{2}', 'x_{3}'], [{'\\overline{x_{1}}', 'x_{1}'}, {'\\overline{x_{2}}', 'x_{2}'}, {'\\overline{x_{3}}', 'x_{3}'}, {'\\overline{x_{3}}', 'x^{0}_{3}'}, {'\\overline{x^{0}_{2}}', 'x_{2}'}, {'\\overline{x_{1}}', 'x^{0}_{1}'}, {'O', '\\overline{x^{0}_{2}}', 'x^{0}_{1}', 'x^{0}_{3}'}])
# ilp_solver = pyo.SolverFactory('cbc') ilp_solver.solve(m).write() print_solution(m)
# ========================================================== # = Solver Results = # ========================================================== # ---------------------------------------------------------- # Problem Information # ---------------------------------------------------------- Problem: - Name: unknown Lower bound: 7.0 Upper bound: 7.0 Number of objectives: 1 Number of constraints: 14 Number of variables: 17 Number of binary variables: 17 Number of integer variables: 17 Number of nonzeros: 7 Sense: maximize # ---------------------------------------------------------- # Solver Information # ---------------------------------------------------------- Solver: - Status: ok User time: -1.0 System time: 0.01 Wallclock time: 0.01 Termination condition: optimal Termination message: Model was solved to optimality (subject to tolerances), and an optimal solution is available. Statistics: Branch and bound: Number of bounded subproblems: 0 Number of created subproblems: 0 Black box: Number of iterations: 0 Error rc: 0 Time: 0.10454320907592773 # ---------------------------------------------------------- # Solution Information # ---------------------------------------------------------- Solution: - number of solutions: 0 number of solutions displayed: 0 x[2] 1.0 x[6] 1.0 x[8] 1.0 x[9] 1.0 y[0] 1.0 y[1] 1.0 y[2] 1.0 y[3] 1.0 y[4] 1.0 y[5] 1.0 y[6] 1.0
selected_items = [m.U[j] for j in m.J if m.x[j].value > 0] selected_items
['\\overline{x_{1}}', 'x^{0}_{3}', 'x_{2}', 'x_{3}']
splitted_sets = [i for i in m.I if m.y[i].value > 0] splitted_sets
[0, 1, 2, 3, 4, 5, 6]
cnf3.clauses
[[3, -2, 1]]
pprint(sets)
{'C_{0}': ['O', 'x^{0}_{3}', '\\overline{x^{0}_{2}}', 'x^{0}_{1}'], 'C_{0}(\\overline{x_{2}})': ['\\overline{x^{0}_{2}}', 'x_{2}'], 'C_{0}(x_{1})': ['x^{0}_{1}', '\\overline{x_{1}}'], 'C_{0}(x_{3})': ['x^{0}_{3}', '\\overline{x_{3}}'], 'x_{1}': ['x_{1}', '\\overline{x_{1}}'], 'x_{2}': ['x_{2}', '\\overline{x_{2}}'], 'x_{3}': ['x_{3}', '\\overline{x_{3}}']}
SVG(psc.subsets2svg(sets, selected_items=selected_items, selected=splitted_sets))
Image in a Jupyter notebook
cnf3 = CNF(from_clauses=psc.rand3cnf(2, 7)) cnf3.clauses
[[-2, -3, 1], [-2, 3, -4]]
sets = cnf32setsplitting(cnf3) pprint(sets)
{'C_{0}': ['O', '\\overline{x^{0}_{2}}', '\\overline{x^{0}_{3}}', 'x^{0}_{1}'], 'C_{0}(\\overline{x_{2}})': ['\\overline{x^{0}_{2}}', 'x_{2}'], 'C_{0}(\\overline{x_{3}})': ['\\overline{x^{0}_{3}}', 'x_{3}'], 'C_{0}(x_{1})': ['x^{0}_{1}', '\\overline{x_{1}}'], 'C_{1}': ['O', '\\overline{x^{1}_{2}}', 'x^{1}_{3}', '\\overline{x^{1}_{4}}'], 'C_{1}(\\overline{x_{2}})': ['\\overline{x^{1}_{2}}', 'x_{2}'], 'C_{1}(\\overline{x_{4}})': ['\\overline{x^{1}_{4}}', 'x_{4}'], 'C_{1}(x_{3})': ['x^{1}_{3}', '\\overline{x_{3}}'], 'x_{1}': ['x_{1}', '\\overline{x_{1}}'], 'x_{2}': ['x_{2}', '\\overline{x_{2}}'], 'x_{3}': ['x_{3}', '\\overline{x_{3}}'], 'x_{4}': ['x_{4}', '\\overline{x_{4}}']}
SVG(psc.subsets2svg(sets))
Image in a Jupyter notebook
m = get_model(sets) m.U, m.S
(['O', '\\overline{x^{0}_{2}}', '\\overline{x^{0}_{3}}', '\\overline{x^{1}_{2}}', '\\overline{x^{1}_{4}}', '\\overline{x_{1}}', '\\overline{x_{2}}', '\\overline{x_{3}}', '\\overline{x_{4}}', 'x^{0}_{1}', 'x^{1}_{3}', 'x_{1}', 'x_{2}', 'x_{3}', 'x_{4}'], [{'\\overline{x_{1}}', 'x_{1}'}, {'\\overline{x_{2}}', 'x_{2}'}, {'\\overline{x_{3}}', 'x_{3}'}, {'\\overline{x_{4}}', 'x_{4}'}, {'\\overline{x^{0}_{2}}', 'x_{2}'}, {'\\overline{x^{0}_{3}}', 'x_{3}'}, {'\\overline{x_{1}}', 'x^{0}_{1}'}, {'O', '\\overline{x^{0}_{2}}', '\\overline{x^{0}_{3}}', 'x^{0}_{1}'}, {'\\overline{x^{1}_{2}}', 'x_{2}'}, {'\\overline{x_{3}}', 'x^{1}_{3}'}, {'\\overline{x^{1}_{4}}', 'x_{4}'}, {'O', '\\overline{x^{1}_{2}}', '\\overline{x^{1}_{4}}', 'x^{1}_{3}'}])
# ilp_solver = pyo.SolverFactory('cbc') ilp_solver.solve(m).write() print_solution(m)
# ========================================================== # = Solver Results = # ========================================================== # ---------------------------------------------------------- # Problem Information # ---------------------------------------------------------- Problem: - Name: unknown Lower bound: 12.0 Upper bound: 12.0 Number of objectives: 1 Number of constraints: 24 Number of variables: 27 Number of binary variables: 27 Number of integer variables: 27 Number of nonzeros: 12 Sense: maximize # ---------------------------------------------------------- # Solver Information # ---------------------------------------------------------- Solver: - Status: ok User time: -1.0 System time: 0.01 Wallclock time: 0.02 Termination condition: optimal Termination message: Model was solved to optimality (subject to tolerances), and an optimal solution is available. Statistics: Branch and bound: Number of bounded subproblems: 0 Number of created subproblems: 0 Black box: Number of iterations: 0 Error rc: 0 Time: 0.16412687301635742 # ---------------------------------------------------------- # Solution Information # ---------------------------------------------------------- Solution: - number of solutions: 0 number of solutions displayed: 0 x[2] 1.0 x[4] 1.0 x[5] 1.0 x[7] 1.0 x[8] 1.0 x[12] 1.0 y[0] 1.0 y[1] 1.0 y[2] 1.0 y[3] 1.0 y[4] 1.0 y[5] 1.0 y[6] 1.0 y[7] 1.0 y[8] 1.0 y[9] 1.0 y[10] 1.0 y[11] 1.0
selected_items = [m.U[j] for j in m.J if m.x[j].value > 0] selected_items
['\\overline{x^{0}_{3}}', '\\overline{x^{1}_{4}}', '\\overline{x_{1}}', '\\overline{x_{3}}', '\\overline{x_{4}}', 'x_{2}']
splitted_sets = [i for i in m.I if m.y[i].value > 0] splitted_sets
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
cnf3.clauses
[[-2, -3, 1], [-2, 3, -4]]
pprint(sets)
{'C_{0}': ['O', '\\overline{x^{0}_{2}}', '\\overline{x^{0}_{3}}', 'x^{0}_{1}'], 'C_{0}(\\overline{x_{2}})': ['\\overline{x^{0}_{2}}', 'x_{2}'], 'C_{0}(\\overline{x_{3}})': ['\\overline{x^{0}_{3}}', 'x_{3}'], 'C_{0}(x_{1})': ['x^{0}_{1}', '\\overline{x_{1}}'], 'C_{1}': ['O', '\\overline{x^{1}_{2}}', 'x^{1}_{3}', '\\overline{x^{1}_{4}}'], 'C_{1}(\\overline{x_{2}})': ['\\overline{x^{1}_{2}}', 'x_{2}'], 'C_{1}(\\overline{x_{4}})': ['\\overline{x^{1}_{4}}', 'x_{4}'], 'C_{1}(x_{3})': ['x^{1}_{3}', '\\overline{x_{3}}'], 'x_{1}': ['x_{1}', '\\overline{x_{1}}'], 'x_{2}': ['x_{2}', '\\overline{x_{2}}'], 'x_{3}': ['x_{3}', '\\overline{x_{3}}'], 'x_{4}': ['x_{4}', '\\overline{x_{4}}']}
SVG(psc.subsets2svg(sets, selected_items=selected_items, selected=splitted_sets))
Image in a Jupyter notebook
import re def max_set_splitting_sol_2_3satsol(m, sets): ''' Конвертация решения этой задачи через ЦЛП, в решение для 3SAT ''' # словарь номер_переменной_в_3SAT → значение (0/1) satsol = {} selected_items = [m.U[j] for j in m.J if m.x[j].value > 0] splitted_sets = [i for i in m.I if m.y[i].value > 0] O_value = m.y[0].value need_negation = O_value re_ = re.compile(r"x\_\{(?P<varn>\d+)\}") for j in m.J: rm = re_.match(m.U[j]) if rm: val = int(m.x[j].value) varn = int(rm.group('varn')) if need_negation: val = not val assert varn not in satsol or val == satsol[varn] satsol[varn] = val return satsol
cnf.clauses
--------------------------------------------------------------------------- NameError Traceback (most recent call last) /var/data/cocalc/1d588dae-0d14-422a-88b4-c470ec2c8303/hard-problems-formulations/maximum-set-splitting.ipynb Cell 46 line 1 ----> <a href='vscode-notebook-cell://xn--17-6kce2c.xn--80apqgfe.xn--p1ai/var/data/cocalc/1d588dae-0d14-422a-88b4-c470ec2c8303/hard-problems-formulations/maximum-set-splitting.ipynb#X63sdnNjb2RlLXJlbW90ZQ%3D%3D?line=0'>1</a> cnf.clauses NameError: name 'cnf' is not defined
max_set_splitting_sol_2_3satsol(m, sets)
{1: True, 2: True, 3: True}
def solve_cnf_by_set_splitting(cnf): sets = cnf32setsplitting(cnf) m = get_model(sets) ilp_solver.solve(m) sol = max_set_splitting_sol_2_3satsol(m, sets) return sol
cnf = CNF(from_clauses=psc.rand3cnf(7, 4)) cnf.clauses, solve_cnf_by_set_splitting(cnf)
([[-3, 1, -2], [-1, 2, 3], [-1, 3, 1], [2, 3, 1], [1, 2, -3], [2, 1, -1], [1, -2, 3]], {1: True, 2: True, 3: True})

Создание Тестов

from pyomo.opt import SolverStatus from pyomo.opt import TerminationCondition
def create_tests(num_of_clauses): cnf = CNF(from_clauses=psc.rand3cnf(num_of_clauses, 3)) test_sets = cnf32setsplitting(cnf) test_model = get_model(test_sets) test_result_struct = ilp_solver.solve(test_model) test_result = (test_result_struct.solver.status == SolverStatus.ok and test_result_struct.solver.termination_condition == TerminationCondition.optimal) test_no_result = (test_result_struct.solver.termination_condition == TerminationCondition.infeasible) py3sat_test_solver = Solver(bootstrap_with=cnf) py3sat_test_result = py3sat_test_solver.solve() if ((py3sat_test_result == True and test_no_result)\ or\ (py3sat_test_result == False and test_result)): print("SOLUTION FAILED num amount: ", num_of_clauses, "Pyomo: ", test_result, ", test no result: ", test_no_result, ", 3SAT: ", py3sat_test_result) return False, test_sets, test_model, py3sat_test_solver.get_model() else: print("SOLUTION FOUND num amount: ", num_of_clauses, ", answer: ", py3sat_test_result) return True, test_sets, test_model, py3sat_test_solver.get_model()
create_tests(5)
SOLUTION FOUND num amount: 5 , answer: True
(True, {'x_{1}': ['x_{1}', '\\overline{x_{1}}'], 'x_{2}': ['x_{2}', '\\overline{x_{2}}'], 'C_{0}(x_{1})': ['x^{0}_{1}', '\\overline{x_{1}}'], 'C_{0}(x_{2})': ['x^{0}_{2}', '\\overline{x_{2}}'], 'C_{0}': ['O', 'x^{0}_{1}', 'x^{0}_{1}', 'x^{0}_{2}'], 'C_{1}(\\overline{x_{1}})': ['\\overline{x^{1}_{1}}', 'x_{1}'], 'C_{1}(\\overline{x_{2}})': ['\\overline{x^{1}_{2}}', 'x_{2}'], 'C_{1}(x_{1})': ['x^{1}_{1}', '\\overline{x_{1}}'], 'C_{1}': ['O', '\\overline{x^{1}_{1}}', '\\overline{x^{1}_{2}}', 'x^{1}_{1}'], 'C_{2}(x_{1})': ['x^{2}_{1}', '\\overline{x_{1}}'], 'C_{2}(\\overline{x_{1}})': ['\\overline{x^{2}_{1}}', 'x_{1}'], 'C_{2}(\\overline{x_{2}})': ['\\overline{x^{2}_{2}}', 'x_{2}'], 'C_{2}': ['O', 'x^{2}_{1}', '\\overline{x^{2}_{1}}', '\\overline{x^{2}_{2}}'], 'C_{3}(x_{1})': ['x^{3}_{1}', '\\overline{x_{1}}'], 'C_{3}(\\overline{x_{1}})': ['\\overline{x^{3}_{1}}', 'x_{1}'], 'C_{3}(x_{2})': ['x^{3}_{2}', '\\overline{x_{2}}'], 'C_{3}': ['O', 'x^{3}_{1}', '\\overline{x^{3}_{1}}', 'x^{3}_{2}'], 'C_{4}(x_{1})': ['x^{4}_{1}', '\\overline{x_{1}}'], 'C_{4}(\\overline{x_{1}})': ['\\overline{x^{4}_{1}}', 'x_{1}'], 'C_{4}(\\overline{x_{2}})': ['\\overline{x^{4}_{2}}', 'x_{2}'], 'C_{4}': ['O', 'x^{4}_{1}', '\\overline{x^{4}_{1}}', '\\overline{x^{4}_{2}}']}, <pyomo.core.base.PyomoModel.ConcreteModel object at 0x7f7b19d77100>, [1, -2])
for i in range(1, 50): result_of_tests = create_tests(i) done = result_of_tests[0] bad_case_sets = result_of_tests[1] model = result_of_tests[2] py3sat_model = result_of_tests[3] if done != True: break
SOLUTION FOUND num amount: 1 , answer: True SOLUTION FOUND num amount: 2 , answer: True SOLUTION FOUND num amount: 3 , answer: True SOLUTION FOUND num amount: 4 , answer: True SOLUTION FOUND num amount: 5 , answer: True SOLUTION FOUND num amount: 6 , answer: True SOLUTION FOUND num amount: 7 , answer: True SOLUTION FOUND num amount: 8 , answer: True SOLUTION FOUND num amount: 9 , answer: True SOLUTION FAILED num amount: 10 Pyomo: True , test no result: False , 3SAT: False
print(bad_case_sets, '\n') bad_case_selected = [model.U[j] for j in model.J if model.x[j].value > 0] bad_case_splitted = [i for i in model.I if model.y[i].value > 0] print("-----\n") print(bad_case_selected) print(bad_case_splitted)
{'x_{1}': ['x_{1}', '\\overline{x_{1}}'], 'x_{2}': ['x_{2}', '\\overline{x_{2}}'], 'C_{0}(x_{1})': ['x^{0}_{1}', '\\overline{x_{1}}'], 'C_{0}(x_{2})': ['x^{0}_{2}', '\\overline{x_{2}}'], 'C_{0}': ['O', 'x^{0}_{1}', 'x^{0}_{1}', 'x^{0}_{2}'], 'C_{1}(x_{1})': ['x^{1}_{1}', '\\overline{x_{1}}'], 'C_{1}(\\overline{x_{2}})': ['\\overline{x^{1}_{2}}', 'x_{2}'], 'C_{1}(\\overline{x_{1}})': ['\\overline{x^{1}_{1}}', 'x_{1}'], 'C_{1}': ['O', 'x^{1}_{1}', '\\overline{x^{1}_{2}}', '\\overline{x^{1}_{1}}'], 'C_{2}(x_{1})': ['x^{2}_{1}', '\\overline{x_{1}}'], 'C_{2}(\\overline{x_{1}})': ['\\overline{x^{2}_{1}}', 'x_{1}'], 'C_{2}(x_{2})': ['x^{2}_{2}', '\\overline{x_{2}}'], 'C_{2}': ['O', 'x^{2}_{1}', '\\overline{x^{2}_{1}}', 'x^{2}_{2}'], 'C_{3}(x_{1})': ['x^{3}_{1}', '\\overline{x_{1}}'], 'C_{3}(x_{2})': ['x^{3}_{2}', '\\overline{x_{2}}'], 'C_{3}': ['O', 'x^{3}_{1}', 'x^{3}_{2}', 'x^{3}_{1}'], 'C_{4}(x_{1})': ['x^{4}_{1}', '\\overline{x_{1}}'], 'C_{4}(x_{2})': ['x^{4}_{2}', '\\overline{x_{2}}'], 'C_{4}': ['O', 'x^{4}_{1}', 'x^{4}_{2}', 'x^{4}_{1}'], 'C_{5}(\\overline{x_{1}})': ['\\overline{x^{5}_{1}}', 'x_{1}'], 'C_{5}(x_{2})': ['x^{5}_{2}', '\\overline{x_{2}}'], 'C_{5}': ['O', '\\overline{x^{5}_{1}}', '\\overline{x^{5}_{1}}', 'x^{5}_{2}'], 'C_{6}(\\overline{x_{1}})': ['\\overline{x^{6}_{1}}', 'x_{1}'], 'C_{6}(x_{2})': ['x^{6}_{2}', '\\overline{x_{2}}'], 'C_{6}(x_{1})': ['x^{6}_{1}', '\\overline{x_{1}}'], 'C_{6}': ['O', '\\overline{x^{6}_{1}}', 'x^{6}_{2}', 'x^{6}_{1}'], 'C_{7}(\\overline{x_{1}})': ['\\overline{x^{7}_{1}}', 'x_{1}'], 'C_{7}(\\overline{x_{2}})': ['\\overline{x^{7}_{2}}', 'x_{2}'], 'C_{7}': ['O', '\\overline{x^{7}_{1}}', '\\overline{x^{7}_{1}}', '\\overline{x^{7}_{2}}'], 'C_{8}(x_{1})': ['x^{8}_{1}', '\\overline{x_{1}}'], 'C_{8}(\\overline{x_{2}})': ['\\overline{x^{8}_{2}}', 'x_{2}'], 'C_{8}': ['O', 'x^{8}_{1}', '\\overline{x^{8}_{2}}', 'x^{8}_{1}'], 'C_{9}(x_{1})': ['x^{9}_{1}', '\\overline{x_{1}}'], 'C_{9}(\\overline{x_{1}})': ['\\overline{x^{9}_{1}}', 'x_{1}'], 'C_{9}(\\overline{x_{2}})': ['\\overline{x^{9}_{2}}', 'x_{2}'], 'C_{9}': ['O', 'x^{9}_{1}', '\\overline{x^{9}_{1}}', '\\overline{x^{9}_{2}}']} ----- ['O', '\\overline{x^{1}_{1}}', '\\overline{x^{2}_{1}}', '\\overline{x^{5}_{1}}', '\\overline{x^{6}_{1}}', '\\overline{x^{7}_{1}}', '\\overline{x^{9}_{1}}', '\\overline{x_{1}}', '\\overline{x_{2}}', 'x_{2}'] [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
SVG(psc.subsets2svg(got_sets, selected_items=result_selected, selected=ssplitted_sets))
Image in a Jupyter notebook

Как можем заметить, мы выявили плохой тест кейс